CM3D2 Converter.misc_VIEW3D_MT_pose_apply

  1# 「3Dビュー」エリア → ポーズモード → Ctrl+A (ポーズ → 適用)
  2import bpy
  3import mathutils
  4from . import common
  5from . import compat
  6
  7
  8# メニュー等に項目追加
  9def menu_func(self, context):
 10    self.layout.separator()
 11    self.layout.operator('pose.apply_prime_field', icon_value=common.kiss_icon())
 12    self.layout.operator('pose.copy_prime_field' , icon_value=common.kiss_icon())
 13
 14@compat.BlRegister()
 15class CNV_OT_copy_prime_field(bpy.types.Operator):
 16    bl_idname = 'pose.copy_prime_field'
 17    bl_label = "Copy Prime Field"
 18    bl_description = "Copies the visual pose of the selected object to the prime field of the active object"
 19    bl_options = {'REGISTER', 'UNDO'}
 20
 21    #is_apply_armature_modifier = bpy.props.BoolProperty(name="Apply Armature Modifier", default=True )
 22    #is_deform_preserve_volume  = bpy.props.BoolProperty(name="Preserve Volume"        , default=True )
 23    #is_keep_original           = bpy.props.BoolProperty(name="Keep Original"          , default=True )
 24    #is_swap_prime_field        = bpy.props.BoolProperty(name="Swap Prime Field"       , default=False)
 25    #is_bake_drivers            = bpy.props.BoolProperty(name="Bake Drivers"           , default=False, description="Enable keyframing of driven properties, locking sliders and twist bones for final apply")
 26    
 27    is_only_selected = bpy.props.BoolProperty(name="Only Selected", default=True )
 28    is_key_location  = bpy.props.BoolProperty(name="Key Location" , default=True )
 29    is_key_rotation  = bpy.props.BoolProperty(name="Key Rotation" , default=True )
 30    is_key_scale     = bpy.props.BoolProperty(name="Key Scale"    , default=True )
 31    is_apply_prime   = bpy.props.BoolProperty(name="Apply Prime"  , default=False, options={'HIDDEN'})
 32    
 33
 34
 35    @classmethod
 36    def poll(cls, context):
 37        target_ob, source_ob = common.get_target_and_source_ob(context)
 38        if target_ob and source_ob:
 39            return True
 40        else:
 41            return False
 42
 43    def invoke(self, context, event):
 44        return context.window_manager.invoke_props_dialog(self)
 45
 46    def draw(self, context):
 47        self.layout.prop(self, 'is_only_selected')
 48        self.layout.prop(self, 'is_key_location' )
 49        self.layout.prop(self, 'is_key_rotation' )
 50        self.layout.prop(self, 'is_key_scale'    )
 51
 52    def execute(self, context):
 53        target_ob, source_ob = common.get_target_and_source_ob(context)
 54        pose = target_ob.pose
 55        arm = target_ob.data
 56
 57        pre_selected_pose_bones = context.selected_pose_bones
 58        pre_mode = target_ob.mode
 59        
 60        bpy.ops.object.mode_set(mode='POSE')
 61        bpy.ops.pose.select_all(action='SELECT')
 62        bpy.ops.pose.constraints_clear()
 63
 64        if not target_ob.pose_library:
 65             bpy.ops.poselib.new()
 66             poselib = target_ob.pose_library
 67
 68        consts = []
 69        bones = pre_selected_pose_bones if self.is_only_selected else pose.bones
 70        for bone in bones:
 71            source_bone = source_ob.pose.bones.get(bone.name)
 72            if source_bone:
 73                if self.is_key_location or self.is_key_rotation:
 74                    const = bone.constraints.new('COPY_TRANSFORMS')
 75                    const.target = source_ob
 76                    const.subtarget = source_bone.name
 77                    consts.append(const)
 78                if self.is_key_scale:
 79                    const = bone.constraints.new('LIMIT_SCALE')
 80                    const.owner_space = 'LOCAL'
 81                    const.use_transform_limit = True
 82                    const.use_min_x = True
 83                    const.use_min_y = True
 84                    const.use_min_z = True
 85                    const.use_max_x = True
 86                    const.use_max_y = True
 87                    const.use_max_z = True
 88                    const.min_x = source_bone.scale.x
 89                    const.min_y = source_bone.scale.y
 90                    const.min_z = source_bone.scale.z
 91                    if source_ob.data.get("is T Stance"):
 92                        source_prime_scale = mathutils.Vector(source_bone.get('prime_scale',(1,1,1)))
 93                        const.min_x *= source_prime_scale.x
 94                        const.min_y *= source_prime_scale.y
 95                        const.min_z *= source_prime_scale.x
 96                    if arm.get("is T Stance"):
 97                        target_prime_scale = mathutils.Vector(bone.get('prime_scale', (1,1,1)))
 98                        const.min_x /= target_prime_scale.x
 99                        const.min_y /= target_prime_scale.y
100                        const.min_z /= target_prime_scale.z
101                    const.max_x = const.min_x
102                    const.max_y = const.min_y
103                    const.max_z = const.min_z
104                    consts.append(const)
105
106        #if True:
107        #    return {'CANCELLED'}
108
109        for i in range(2):
110            is_prime_frame = not bool(i % 2) if arm.get("is T Stance") else bool(i % 2)
111            pose_name = '__prime_field_pose' if is_prime_frame else '__base_field_pose'
112            if self.is_apply_prime:
113                is_prime_frame = not is_prime_frame
114            
115            #if self.is_key_scale and is_prime_frame:
116            #    for const in consts:
117            #        if const.type == 'LIMIT_SCALE':
118            #            const.mute = not is_prime_frame
119            #    bpy.ops.pose.visual_transform_apply()
120            #    for bone in pose.bones:
121            #        bone.keyframe_insert(data_path='scale', frame=i, group=bone.name)
122            #    for const in consts:
123            #        if const.type == 'LIMIT_SCALE':
124            #            const.mute = is_prime_frame
125            
126            for const in consts:
127                const.mute = not is_prime_frame
128            if is_prime_frame:
129                bpy.ops.pose.visual_transform_apply()
130            else:
131                bpy.ops.pose.transforms_clear()
132            for bone in pose.bones:
133                if self.is_key_location:
134                    bone.keyframe_insert(data_path='location'           , frame=i, group=bone.name)
135                if self.is_key_rotation:
136                    bone.keyframe_insert(data_path='rotation_euler'     , frame=i, group=bone.name)
137                    bone.keyframe_insert(data_path='rotation_quaternion', frame=i, group=bone.name)
138                if self.is_key_scale: # and not is_prime_frame:
139                    bone.keyframe_insert(data_path='scale'              , frame=i, group=bone.name)
140                bpy.ops.poselib.pose_add(frame=i, name=pose_name)
141
142        bpy.ops.pose.constraints_clear()
143        bpy.ops.pose.transforms_clear()
144        target_ob.animation_data_clear()
145
146        bpy.ops.pose.select_all(action='DESELECT')
147        if pre_selected_pose_bones:
148            for bone in pre_selected_pose_bones:
149                arm.bones[bone.name].select = True
150
151        if pre_mode: 
152            bpy.ops.object.mode_set(mode=pre_mode)
153        
154        return {'FINISHED'}
155
156
157@compat.BlRegister()
158class CNV_OT_apply_prime_field(bpy.types.Operator):
159    bl_idname = 'pose.apply_prime_field'
160    bl_label = "現在のポーズで素体化"
161    bl_description = "現在のポーズで衣装をモデリングしやすくする素体を作成します"
162    bl_options = {'REGISTER', 'UNDO'}
163
164    is_apply_armature_modifier   = bpy.props.BoolProperty(name="関係するメッシュのアーマチュアを適用", default=True)
165    is_preserve_shape_key_values = bpy.props.BoolProperty(name="Preserve Shape Key Values", default=True , description="Ensure shape key values of child mesh objects are not changed")
166    is_deform_preserve_volume    = bpy.props.BoolProperty(name="アーマチュア適用は体積を維持", default=True)
167    is_keep_original             = bpy.props.BoolProperty(name="Keep Original"            , default=True , description="If the armature is already primed, don't replace the base pose with the current rest pose")
168    is_swap_prime_field          = bpy.props.BoolProperty(name="Swap Prime Field"         , default=False)
169    #is_bake_drivers              = bpy.props.BoolProperty(name="Bake Drivers"             , default=False, description="Enable keyframing of driven properties, locking sliders and twist bones for final apply")
170    
171    
172    was_t_stance = False
173
174    @classmethod
175    def poll(cls, context):
176        ob = context.active_object
177        if ob and ob.type == 'ARMATURE':
178            return True
179        return False
180
181    def invoke(self, context, event):
182        self.was_t_stance = context.object.data.get('is T Stance')
183        return context.window_manager.invoke_props_dialog(self)
184
185    def draw(self, context):
186        self.layout.prop(self, 'is_apply_armature_modifier')
187
188        col = self.layout.column()
189        col.enabled = self.is_apply_armature_modifier
190        col.prop(self , 'is_preserve_shape_key_values')
191        col.prop(self , 'is_deform_preserve_volume'   )
192        if compat.IS_LEGACY:
193            col.prop(prefs, 'custom_normal_blend', icon=compat.icon('SNAP_NORMAL'  ), slider=True)
194
195        self.layout.prop(self, 'is_bake_drivers')
196        if self.was_t_stance:
197            self.layout.prop(self, 'is_keep_original')
198
199    def execute(self, context):
200        ob = context.active_object
201        arm = ob.data
202        pose = ob.pose
203        progress = 0
204
205        pre_selected_objects = context.selected_objects
206        pre_selected_pose_bones = context.selected_pose_bones
207        pre_mode = ob.mode
208        pre_frame = context.scene.frame_current
209
210        bpy.ops.object.mode_set(mode='OBJECT')
211        bpy.ops.object.select_all(action='DESELECT')
212        compat.set_select(ob, True)
213
214        if self.is_swap_prime_field:
215            #context.scene.frame_set(1)
216            bpy.ops.poselib.apply_pose(pose_index=1)
217            bpy.context.view_layer.update()
218
219        if self.is_apply_armature_modifier and ob.children:
220            override = context.copy()
221            context.window_manager.progress_begin(0, len(ob.children)+1)  
222            for child in ob.children:
223                override['object'], override['active_object'] = child, child
224                if child.type == 'MESH' and len(child.modifiers) and bpy.ops.object.forced_modifier_apply.poll(override):
225                    for mod in child.modifiers:
226                        if mod.type == 'ARMATURE':
227                            mod.use_deform_preserve_volume = self.is_deform_preserve_volume
228                            if not mod.object == ob:
229                                had_armature = False
230                            else:
231                                had_armature = True
232                                old_name                = mod.name                      
233                                old_show_expanded       = mod.show_expanded             
234                                old_show_in_editmode    = mod.show_in_editmode          
235                                old_show_on_cage        = mod.show_on_cage              
236                                old_show_render         = mod.show_render               
237                                old_show_viewport       = mod.show_viewport             
238                                old_use_apply_on_spline = mod.use_apply_on_spline       
239                                old_invert_vertex_group = mod.invert_vertex_group       
240                                old_use_bone_envelopes  = mod.use_bone_envelopes        
241                                #old_use_multi_modifier  = mod.use_multi_modifier        
242                                old_use_vertex_groups   = mod.use_vertex_groups         
243                                old_vertex_group        = mod.vertex_group        
244                    apply_results = bpy.ops.object.forced_modifier_apply(override, apply_viewport_visible=True, is_preserve_shape_key_values=self.is_preserve_shape_key_values, initial_progress=progress)
245                    if ('FINISHED' in apply_results) and had_armature:
246                        new_mod = child.modifiers.new(name=old_name, type='ARMATURE')
247                        new_mod.object              = ob
248                        new_mod.use_deform_preserve_volume = self.is_deform_preserve_volume
249                        new_mod.show_expanded       = old_show_expanded      
250                        new_mod.show_in_editmode    = old_show_in_editmode   
251                        new_mod.show_on_cage        = old_show_on_cage       
252                        new_mod.show_render         = old_show_render        
253                        new_mod.show_viewport       = old_show_viewport      
254                        new_mod.use_apply_on_spline = old_use_apply_on_spline
255                        new_mod.invert_vertex_group = old_invert_vertex_group
256                        new_mod.use_bone_envelopes  = old_use_bone_envelopes 
257                        #new_mod.use_multi_modifier  = old_use_multi_modifier 
258                        new_mod.use_vertex_groups   = old_use_vertex_groups  
259                        new_mod.vertex_group        = old_vertex_group
260                
261                progress += 1
262                context.window_manager.progress_update(progress)
263
264        else:
265            context.window_manager.progress_begin(0, 1)  
266
267        temp_ob = ob.copy()
268        temp_arm = arm.copy()
269        temp_ob.data = temp_arm
270        compat.link(context.scene, temp_ob)
271        
272        compat.set_active(context, ob)
273        bpy.ops.object.mode_set(mode='POSE')
274        bpy.ops.pose.select_all(action='SELECT')
275        for bone in ob.pose.bones:
276            prime_scale = mathutils.Vector(bone.get('prime_scale', (1.0,1.0,1.0)))
277            bone_scale = bone.scale #bone.matrix.to_scale()
278            prime_scale.x *= bone_scale.x
279            prime_scale.y *= bone_scale.y
280            prime_scale.z *= bone_scale.z
281            bone['prime_scale'] = prime_scale
282            #bone['_RNA_UI']['prime_scale']['subtype'] = 'XYZ'
283        bpy.ops.pose.armature_apply()
284        bpy.ops.pose.constraints_clear()
285        ob.animation_data_clear()
286        
287        if arm.get("is T Stance") and self.is_keep_original and not self.is_swap_prime_field:
288            anim_data = temp_ob.animation_data
289            if anim_data and anim_data.drivers:
290                drivers = anim_data.drivers
291                for driver in drivers.values():
292                    drivers.remove(driver)
293            #context.scene.frame_set(1)
294            bpy.ops.pose.user_transforms_clear()
295            bpy.ops.poselib.apply_pose(pose_index=1)
296        else:
297            compat.set_active(context, temp_ob)
298            bpy.ops.object.mode_set(mode='POSE')
299            bpy.ops.pose.select_all(action='SELECT')
300            temp_ob.animation_data_clear()
301            bpy.ops.pose.transforms_clear()
302            bpy.ops.object.mode_set(mode='OBJECT')
303            compat.set_select(temp_ob, False)
304        
305        if self.is_swap_prime_field and arm.get('is T Stance'):
306            arm['is T Stance'] = False
307        else:
308            arm['is T Stance'] = True
309
310        # CNV_OT_copy_prime_field.execute()
311        compat.set_select(temp_ob, True)
312        compat.set_active(context, ob)
313        bpy.context.view_layer.update()
314        response = bpy.ops.pose.copy_prime_field(is_only_selected=False, is_key_location=True, is_key_scale=True, is_apply_prime=(not self.is_swap_prime_field))#is_key_location=self.is_bake_drivers, is_key_scale=self.is_bake_drivers, is_apply_prime=True)
315
316        context.window_manager.progress_end()
317
318        if not 'FINISHED' in response:
319            return response
320
321        common.remove_data(temp_arm)
322        try:
323            common.remove_data(temp_ob)
324        except:
325            pass
326        
327        bpy.ops.object.mode_set(mode='POSE')
328        bpy.ops.pose.select_all(action='DESELECT')
329        if pre_selected_pose_bones:
330            for bone in pre_selected_pose_bones:
331                arm.bones[bone.name].select = True
332
333        if pre_selected_objects:
334            for o in pre_selected_objects:
335                compat.set_select(o, True)
336        compat.set_active(context, ob)
337        bpy.ops.object.mode_set(mode=pre_mode)
338
339        context.scene.frame_set(pre_frame)
340
341
342
343        return {'FINISHED'}
@compat.BlRegister()
class CNV_OT_copy_prime_field(bpy_types.Operator):
 15@compat.BlRegister()
 16class CNV_OT_copy_prime_field(bpy.types.Operator):
 17    bl_idname = 'pose.copy_prime_field'
 18    bl_label = "Copy Prime Field"
 19    bl_description = "Copies the visual pose of the selected object to the prime field of the active object"
 20    bl_options = {'REGISTER', 'UNDO'}
 21
 22    #is_apply_armature_modifier = bpy.props.BoolProperty(name="Apply Armature Modifier", default=True )
 23    #is_deform_preserve_volume  = bpy.props.BoolProperty(name="Preserve Volume"        , default=True )
 24    #is_keep_original           = bpy.props.BoolProperty(name="Keep Original"          , default=True )
 25    #is_swap_prime_field        = bpy.props.BoolProperty(name="Swap Prime Field"       , default=False)
 26    #is_bake_drivers            = bpy.props.BoolProperty(name="Bake Drivers"           , default=False, description="Enable keyframing of driven properties, locking sliders and twist bones for final apply")
 27    
 28    is_only_selected = bpy.props.BoolProperty(name="Only Selected", default=True )
 29    is_key_location  = bpy.props.BoolProperty(name="Key Location" , default=True )
 30    is_key_rotation  = bpy.props.BoolProperty(name="Key Rotation" , default=True )
 31    is_key_scale     = bpy.props.BoolProperty(name="Key Scale"    , default=True )
 32    is_apply_prime   = bpy.props.BoolProperty(name="Apply Prime"  , default=False, options={'HIDDEN'})
 33    
 34
 35
 36    @classmethod
 37    def poll(cls, context):
 38        target_ob, source_ob = common.get_target_and_source_ob(context)
 39        if target_ob and source_ob:
 40            return True
 41        else:
 42            return False
 43
 44    def invoke(self, context, event):
 45        return context.window_manager.invoke_props_dialog(self)
 46
 47    def draw(self, context):
 48        self.layout.prop(self, 'is_only_selected')
 49        self.layout.prop(self, 'is_key_location' )
 50        self.layout.prop(self, 'is_key_rotation' )
 51        self.layout.prop(self, 'is_key_scale'    )
 52
 53    def execute(self, context):
 54        target_ob, source_ob = common.get_target_and_source_ob(context)
 55        pose = target_ob.pose
 56        arm = target_ob.data
 57
 58        pre_selected_pose_bones = context.selected_pose_bones
 59        pre_mode = target_ob.mode
 60        
 61        bpy.ops.object.mode_set(mode='POSE')
 62        bpy.ops.pose.select_all(action='SELECT')
 63        bpy.ops.pose.constraints_clear()
 64
 65        if not target_ob.pose_library:
 66             bpy.ops.poselib.new()
 67             poselib = target_ob.pose_library
 68
 69        consts = []
 70        bones = pre_selected_pose_bones if self.is_only_selected else pose.bones
 71        for bone in bones:
 72            source_bone = source_ob.pose.bones.get(bone.name)
 73            if source_bone:
 74                if self.is_key_location or self.is_key_rotation:
 75                    const = bone.constraints.new('COPY_TRANSFORMS')
 76                    const.target = source_ob
 77                    const.subtarget = source_bone.name
 78                    consts.append(const)
 79                if self.is_key_scale:
 80                    const = bone.constraints.new('LIMIT_SCALE')
 81                    const.owner_space = 'LOCAL'
 82                    const.use_transform_limit = True
 83                    const.use_min_x = True
 84                    const.use_min_y = True
 85                    const.use_min_z = True
 86                    const.use_max_x = True
 87                    const.use_max_y = True
 88                    const.use_max_z = True
 89                    const.min_x = source_bone.scale.x
 90                    const.min_y = source_bone.scale.y
 91                    const.min_z = source_bone.scale.z
 92                    if source_ob.data.get("is T Stance"):
 93                        source_prime_scale = mathutils.Vector(source_bone.get('prime_scale',(1,1,1)))
 94                        const.min_x *= source_prime_scale.x
 95                        const.min_y *= source_prime_scale.y
 96                        const.min_z *= source_prime_scale.x
 97                    if arm.get("is T Stance"):
 98                        target_prime_scale = mathutils.Vector(bone.get('prime_scale', (1,1,1)))
 99                        const.min_x /= target_prime_scale.x
100                        const.min_y /= target_prime_scale.y
101                        const.min_z /= target_prime_scale.z
102                    const.max_x = const.min_x
103                    const.max_y = const.min_y
104                    const.max_z = const.min_z
105                    consts.append(const)
106
107        #if True:
108        #    return {'CANCELLED'}
109
110        for i in range(2):
111            is_prime_frame = not bool(i % 2) if arm.get("is T Stance") else bool(i % 2)
112            pose_name = '__prime_field_pose' if is_prime_frame else '__base_field_pose'
113            if self.is_apply_prime:
114                is_prime_frame = not is_prime_frame
115            
116            #if self.is_key_scale and is_prime_frame:
117            #    for const in consts:
118            #        if const.type == 'LIMIT_SCALE':
119            #            const.mute = not is_prime_frame
120            #    bpy.ops.pose.visual_transform_apply()
121            #    for bone in pose.bones:
122            #        bone.keyframe_insert(data_path='scale', frame=i, group=bone.name)
123            #    for const in consts:
124            #        if const.type == 'LIMIT_SCALE':
125            #            const.mute = is_prime_frame
126            
127            for const in consts:
128                const.mute = not is_prime_frame
129            if is_prime_frame:
130                bpy.ops.pose.visual_transform_apply()
131            else:
132                bpy.ops.pose.transforms_clear()
133            for bone in pose.bones:
134                if self.is_key_location:
135                    bone.keyframe_insert(data_path='location'           , frame=i, group=bone.name)
136                if self.is_key_rotation:
137                    bone.keyframe_insert(data_path='rotation_euler'     , frame=i, group=bone.name)
138                    bone.keyframe_insert(data_path='rotation_quaternion', frame=i, group=bone.name)
139                if self.is_key_scale: # and not is_prime_frame:
140                    bone.keyframe_insert(data_path='scale'              , frame=i, group=bone.name)
141                bpy.ops.poselib.pose_add(frame=i, name=pose_name)
142
143        bpy.ops.pose.constraints_clear()
144        bpy.ops.pose.transforms_clear()
145        target_ob.animation_data_clear()
146
147        bpy.ops.pose.select_all(action='DESELECT')
148        if pre_selected_pose_bones:
149            for bone in pre_selected_pose_bones:
150                arm.bones[bone.name].select = True
151
152        if pre_mode: 
153            bpy.ops.object.mode_set(mode=pre_mode)
154        
155        return {'FINISHED'}
bl_idname = 'pose.copy_prime_field'
bl_label = 'Copy Prime Field'
bl_description = 'Copies the visual pose of the selected object to the prime field of the active object'
bl_options = {'REGISTER', 'UNDO'}
is_only_selected: <_PropertyDeferred, <built-in function BoolProperty>, {'name': 'Only Selected', 'default': True, 'attr': 'is_only_selected'}> = <_PropertyDeferred, <built-in function BoolProperty>, {'name': 'Only Selected', 'default': True, 'attr': 'is_only_selected'}>
is_key_location: <_PropertyDeferred, <built-in function BoolProperty>, {'name': 'Key Location', 'default': True, 'attr': 'is_key_location'}> = <_PropertyDeferred, <built-in function BoolProperty>, {'name': 'Key Location', 'default': True, 'attr': 'is_key_location'}>
is_key_rotation: <_PropertyDeferred, <built-in function BoolProperty>, {'name': 'Key Rotation', 'default': True, 'attr': 'is_key_rotation'}> = <_PropertyDeferred, <built-in function BoolProperty>, {'name': 'Key Rotation', 'default': True, 'attr': 'is_key_rotation'}>
is_key_scale: <_PropertyDeferred, <built-in function BoolProperty>, {'name': 'Key Scale', 'default': True, 'attr': 'is_key_scale'}> = <_PropertyDeferred, <built-in function BoolProperty>, {'name': 'Key Scale', 'default': True, 'attr': 'is_key_scale'}>
is_apply_prime: <_PropertyDeferred, <built-in function BoolProperty>, {'name': 'Apply Prime', 'default': False, 'options': {'HIDDEN'}, 'attr': 'is_apply_prime'}> = <_PropertyDeferred, <built-in function BoolProperty>, {'name': 'Apply Prime', 'default': False, 'options': {'HIDDEN'}, 'attr': 'is_apply_prime'}>
@classmethod
def poll(cls, context):
36    @classmethod
37    def poll(cls, context):
38        target_ob, source_ob = common.get_target_and_source_ob(context)
39        if target_ob and source_ob:
40            return True
41        else:
42            return False
def invoke(self, context, event):
44    def invoke(self, context, event):
45        return context.window_manager.invoke_props_dialog(self)
def draw(self, context):
47    def draw(self, context):
48        self.layout.prop(self, 'is_only_selected')
49        self.layout.prop(self, 'is_key_location' )
50        self.layout.prop(self, 'is_key_rotation' )
51        self.layout.prop(self, 'is_key_scale'    )
def execute(self, context):
 53    def execute(self, context):
 54        target_ob, source_ob = common.get_target_and_source_ob(context)
 55        pose = target_ob.pose
 56        arm = target_ob.data
 57
 58        pre_selected_pose_bones = context.selected_pose_bones
 59        pre_mode = target_ob.mode
 60        
 61        bpy.ops.object.mode_set(mode='POSE')
 62        bpy.ops.pose.select_all(action='SELECT')
 63        bpy.ops.pose.constraints_clear()
 64
 65        if not target_ob.pose_library:
 66             bpy.ops.poselib.new()
 67             poselib = target_ob.pose_library
 68
 69        consts = []
 70        bones = pre_selected_pose_bones if self.is_only_selected else pose.bones
 71        for bone in bones:
 72            source_bone = source_ob.pose.bones.get(bone.name)
 73            if source_bone:
 74                if self.is_key_location or self.is_key_rotation:
 75                    const = bone.constraints.new('COPY_TRANSFORMS')
 76                    const.target = source_ob
 77                    const.subtarget = source_bone.name
 78                    consts.append(const)
 79                if self.is_key_scale:
 80                    const = bone.constraints.new('LIMIT_SCALE')
 81                    const.owner_space = 'LOCAL'
 82                    const.use_transform_limit = True
 83                    const.use_min_x = True
 84                    const.use_min_y = True
 85                    const.use_min_z = True
 86                    const.use_max_x = True
 87                    const.use_max_y = True
 88                    const.use_max_z = True
 89                    const.min_x = source_bone.scale.x
 90                    const.min_y = source_bone.scale.y
 91                    const.min_z = source_bone.scale.z
 92                    if source_ob.data.get("is T Stance"):
 93                        source_prime_scale = mathutils.Vector(source_bone.get('prime_scale',(1,1,1)))
 94                        const.min_x *= source_prime_scale.x
 95                        const.min_y *= source_prime_scale.y
 96                        const.min_z *= source_prime_scale.x
 97                    if arm.get("is T Stance"):
 98                        target_prime_scale = mathutils.Vector(bone.get('prime_scale', (1,1,1)))
 99                        const.min_x /= target_prime_scale.x
100                        const.min_y /= target_prime_scale.y
101                        const.min_z /= target_prime_scale.z
102                    const.max_x = const.min_x
103                    const.max_y = const.min_y
104                    const.max_z = const.min_z
105                    consts.append(const)
106
107        #if True:
108        #    return {'CANCELLED'}
109
110        for i in range(2):
111            is_prime_frame = not bool(i % 2) if arm.get("is T Stance") else bool(i % 2)
112            pose_name = '__prime_field_pose' if is_prime_frame else '__base_field_pose'
113            if self.is_apply_prime:
114                is_prime_frame = not is_prime_frame
115            
116            #if self.is_key_scale and is_prime_frame:
117            #    for const in consts:
118            #        if const.type == 'LIMIT_SCALE':
119            #            const.mute = not is_prime_frame
120            #    bpy.ops.pose.visual_transform_apply()
121            #    for bone in pose.bones:
122            #        bone.keyframe_insert(data_path='scale', frame=i, group=bone.name)
123            #    for const in consts:
124            #        if const.type == 'LIMIT_SCALE':
125            #            const.mute = is_prime_frame
126            
127            for const in consts:
128                const.mute = not is_prime_frame
129            if is_prime_frame:
130                bpy.ops.pose.visual_transform_apply()
131            else:
132                bpy.ops.pose.transforms_clear()
133            for bone in pose.bones:
134                if self.is_key_location:
135                    bone.keyframe_insert(data_path='location'           , frame=i, group=bone.name)
136                if self.is_key_rotation:
137                    bone.keyframe_insert(data_path='rotation_euler'     , frame=i, group=bone.name)
138                    bone.keyframe_insert(data_path='rotation_quaternion', frame=i, group=bone.name)
139                if self.is_key_scale: # and not is_prime_frame:
140                    bone.keyframe_insert(data_path='scale'              , frame=i, group=bone.name)
141                bpy.ops.poselib.pose_add(frame=i, name=pose_name)
142
143        bpy.ops.pose.constraints_clear()
144        bpy.ops.pose.transforms_clear()
145        target_ob.animation_data_clear()
146
147        bpy.ops.pose.select_all(action='DESELECT')
148        if pre_selected_pose_bones:
149            for bone in pre_selected_pose_bones:
150                arm.bones[bone.name].select = True
151
152        if pre_mode: 
153            bpy.ops.object.mode_set(mode=pre_mode)
154        
155        return {'FINISHED'}
bl_rna = <bpy_struct, Struct("POSE_OT_copy_prime_field")>
Inherited Members
bpy_types.Operator
as_keywords
poll_message_set
builtins.bpy_struct
keys
values
items
get
pop
as_pointer
keyframe_insert
keyframe_delete
driver_add
driver_remove
is_property_set
property_unset
is_property_hidden
is_property_readonly
is_property_overridable_library
property_overridable_library_set
path_resolve
path_from_id
type_recast
bl_rna_get_subclass_py
bl_rna_get_subclass
id_properties_ensure
id_properties_clear
id_properties_ui
id_data
@compat.BlRegister()
class CNV_OT_apply_prime_field(bpy_types.Operator):
158@compat.BlRegister()
159class CNV_OT_apply_prime_field(bpy.types.Operator):
160    bl_idname = 'pose.apply_prime_field'
161    bl_label = "現在のポーズで素体化"
162    bl_description = "現在のポーズで衣装をモデリングしやすくする素体を作成します"
163    bl_options = {'REGISTER', 'UNDO'}
164
165    is_apply_armature_modifier   = bpy.props.BoolProperty(name="関係するメッシュのアーマチュアを適用", default=True)
166    is_preserve_shape_key_values = bpy.props.BoolProperty(name="Preserve Shape Key Values", default=True , description="Ensure shape key values of child mesh objects are not changed")
167    is_deform_preserve_volume    = bpy.props.BoolProperty(name="アーマチュア適用は体積を維持", default=True)
168    is_keep_original             = bpy.props.BoolProperty(name="Keep Original"            , default=True , description="If the armature is already primed, don't replace the base pose with the current rest pose")
169    is_swap_prime_field          = bpy.props.BoolProperty(name="Swap Prime Field"         , default=False)
170    #is_bake_drivers              = bpy.props.BoolProperty(name="Bake Drivers"             , default=False, description="Enable keyframing of driven properties, locking sliders and twist bones for final apply")
171    
172    
173    was_t_stance = False
174
175    @classmethod
176    def poll(cls, context):
177        ob = context.active_object
178        if ob and ob.type == 'ARMATURE':
179            return True
180        return False
181
182    def invoke(self, context, event):
183        self.was_t_stance = context.object.data.get('is T Stance')
184        return context.window_manager.invoke_props_dialog(self)
185
186    def draw(self, context):
187        self.layout.prop(self, 'is_apply_armature_modifier')
188
189        col = self.layout.column()
190        col.enabled = self.is_apply_armature_modifier
191        col.prop(self , 'is_preserve_shape_key_values')
192        col.prop(self , 'is_deform_preserve_volume'   )
193        if compat.IS_LEGACY:
194            col.prop(prefs, 'custom_normal_blend', icon=compat.icon('SNAP_NORMAL'  ), slider=True)
195
196        self.layout.prop(self, 'is_bake_drivers')
197        if self.was_t_stance:
198            self.layout.prop(self, 'is_keep_original')
199
200    def execute(self, context):
201        ob = context.active_object
202        arm = ob.data
203        pose = ob.pose
204        progress = 0
205
206        pre_selected_objects = context.selected_objects
207        pre_selected_pose_bones = context.selected_pose_bones
208        pre_mode = ob.mode
209        pre_frame = context.scene.frame_current
210
211        bpy.ops.object.mode_set(mode='OBJECT')
212        bpy.ops.object.select_all(action='DESELECT')
213        compat.set_select(ob, True)
214
215        if self.is_swap_prime_field:
216            #context.scene.frame_set(1)
217            bpy.ops.poselib.apply_pose(pose_index=1)
218            bpy.context.view_layer.update()
219
220        if self.is_apply_armature_modifier and ob.children:
221            override = context.copy()
222            context.window_manager.progress_begin(0, len(ob.children)+1)  
223            for child in ob.children:
224                override['object'], override['active_object'] = child, child
225                if child.type == 'MESH' and len(child.modifiers) and bpy.ops.object.forced_modifier_apply.poll(override):
226                    for mod in child.modifiers:
227                        if mod.type == 'ARMATURE':
228                            mod.use_deform_preserve_volume = self.is_deform_preserve_volume
229                            if not mod.object == ob:
230                                had_armature = False
231                            else:
232                                had_armature = True
233                                old_name                = mod.name                      
234                                old_show_expanded       = mod.show_expanded             
235                                old_show_in_editmode    = mod.show_in_editmode          
236                                old_show_on_cage        = mod.show_on_cage              
237                                old_show_render         = mod.show_render               
238                                old_show_viewport       = mod.show_viewport             
239                                old_use_apply_on_spline = mod.use_apply_on_spline       
240                                old_invert_vertex_group = mod.invert_vertex_group       
241                                old_use_bone_envelopes  = mod.use_bone_envelopes        
242                                #old_use_multi_modifier  = mod.use_multi_modifier        
243                                old_use_vertex_groups   = mod.use_vertex_groups         
244                                old_vertex_group        = mod.vertex_group        
245                    apply_results = bpy.ops.object.forced_modifier_apply(override, apply_viewport_visible=True, is_preserve_shape_key_values=self.is_preserve_shape_key_values, initial_progress=progress)
246                    if ('FINISHED' in apply_results) and had_armature:
247                        new_mod = child.modifiers.new(name=old_name, type='ARMATURE')
248                        new_mod.object              = ob
249                        new_mod.use_deform_preserve_volume = self.is_deform_preserve_volume
250                        new_mod.show_expanded       = old_show_expanded      
251                        new_mod.show_in_editmode    = old_show_in_editmode   
252                        new_mod.show_on_cage        = old_show_on_cage       
253                        new_mod.show_render         = old_show_render        
254                        new_mod.show_viewport       = old_show_viewport      
255                        new_mod.use_apply_on_spline = old_use_apply_on_spline
256                        new_mod.invert_vertex_group = old_invert_vertex_group
257                        new_mod.use_bone_envelopes  = old_use_bone_envelopes 
258                        #new_mod.use_multi_modifier  = old_use_multi_modifier 
259                        new_mod.use_vertex_groups   = old_use_vertex_groups  
260                        new_mod.vertex_group        = old_vertex_group
261                
262                progress += 1
263                context.window_manager.progress_update(progress)
264
265        else:
266            context.window_manager.progress_begin(0, 1)  
267
268        temp_ob = ob.copy()
269        temp_arm = arm.copy()
270        temp_ob.data = temp_arm
271        compat.link(context.scene, temp_ob)
272        
273        compat.set_active(context, ob)
274        bpy.ops.object.mode_set(mode='POSE')
275        bpy.ops.pose.select_all(action='SELECT')
276        for bone in ob.pose.bones:
277            prime_scale = mathutils.Vector(bone.get('prime_scale', (1.0,1.0,1.0)))
278            bone_scale = bone.scale #bone.matrix.to_scale()
279            prime_scale.x *= bone_scale.x
280            prime_scale.y *= bone_scale.y
281            prime_scale.z *= bone_scale.z
282            bone['prime_scale'] = prime_scale
283            #bone['_RNA_UI']['prime_scale']['subtype'] = 'XYZ'
284        bpy.ops.pose.armature_apply()
285        bpy.ops.pose.constraints_clear()
286        ob.animation_data_clear()
287        
288        if arm.get("is T Stance") and self.is_keep_original and not self.is_swap_prime_field:
289            anim_data = temp_ob.animation_data
290            if anim_data and anim_data.drivers:
291                drivers = anim_data.drivers
292                for driver in drivers.values():
293                    drivers.remove(driver)
294            #context.scene.frame_set(1)
295            bpy.ops.pose.user_transforms_clear()
296            bpy.ops.poselib.apply_pose(pose_index=1)
297        else:
298            compat.set_active(context, temp_ob)
299            bpy.ops.object.mode_set(mode='POSE')
300            bpy.ops.pose.select_all(action='SELECT')
301            temp_ob.animation_data_clear()
302            bpy.ops.pose.transforms_clear()
303            bpy.ops.object.mode_set(mode='OBJECT')
304            compat.set_select(temp_ob, False)
305        
306        if self.is_swap_prime_field and arm.get('is T Stance'):
307            arm['is T Stance'] = False
308        else:
309            arm['is T Stance'] = True
310
311        # CNV_OT_copy_prime_field.execute()
312        compat.set_select(temp_ob, True)
313        compat.set_active(context, ob)
314        bpy.context.view_layer.update()
315        response = bpy.ops.pose.copy_prime_field(is_only_selected=False, is_key_location=True, is_key_scale=True, is_apply_prime=(not self.is_swap_prime_field))#is_key_location=self.is_bake_drivers, is_key_scale=self.is_bake_drivers, is_apply_prime=True)
316
317        context.window_manager.progress_end()
318
319        if not 'FINISHED' in response:
320            return response
321
322        common.remove_data(temp_arm)
323        try:
324            common.remove_data(temp_ob)
325        except:
326            pass
327        
328        bpy.ops.object.mode_set(mode='POSE')
329        bpy.ops.pose.select_all(action='DESELECT')
330        if pre_selected_pose_bones:
331            for bone in pre_selected_pose_bones:
332                arm.bones[bone.name].select = True
333
334        if pre_selected_objects:
335            for o in pre_selected_objects:
336                compat.set_select(o, True)
337        compat.set_active(context, ob)
338        bpy.ops.object.mode_set(mode=pre_mode)
339
340        context.scene.frame_set(pre_frame)
341
342
343
344        return {'FINISHED'}
bl_idname = 'pose.apply_prime_field'
bl_label = '現在のポーズで素体化'
bl_description = '現在のポーズで衣装をモデリングしやすくする素体を作成します'
bl_options = {'REGISTER', 'UNDO'}
is_apply_armature_modifier: <_PropertyDeferred, <built-in function BoolProperty>, {'name': '関係するメッシュのアーマチュアを適用', 'default': True, 'attr': 'is_apply_armature_modifier'}> = <_PropertyDeferred, <built-in function BoolProperty>, {'name': '関係するメッシュのアーマチュアを適用', 'default': True, 'attr': 'is_apply_armature_modifier'}>
is_preserve_shape_key_values: <_PropertyDeferred, <built-in function BoolProperty>, {'name': 'Preserve Shape Key Values', 'default': True, 'description': 'Ensure shape key values of child mesh objects are not changed', 'attr': 'is_preserve_shape_key_values'}> = <_PropertyDeferred, <built-in function BoolProperty>, {'name': 'Preserve Shape Key Values', 'default': True, 'description': 'Ensure shape key values of child mesh objects are not changed', 'attr': 'is_preserve_shape_key_values'}>
is_deform_preserve_volume: <_PropertyDeferred, <built-in function BoolProperty>, {'name': 'アーマチュア適用は体積を維持', 'default': True, 'attr': 'is_deform_preserve_volume'}> = <_PropertyDeferred, <built-in function BoolProperty>, {'name': 'アーマチュア適用は体積を維持', 'default': True, 'attr': 'is_deform_preserve_volume'}>
is_keep_original: <_PropertyDeferred, <built-in function BoolProperty>, {'name': 'Keep Original', 'default': True, 'description': "If the armature is already primed, don't replace the base pose with the current rest pose", 'attr': 'is_keep_original'}> = <_PropertyDeferred, <built-in function BoolProperty>, {'name': 'Keep Original', 'default': True, 'description': "If the armature is already primed, don't replace the base pose with the current rest pose", 'attr': 'is_keep_original'}>
is_swap_prime_field: <_PropertyDeferred, <built-in function BoolProperty>, {'name': 'Swap Prime Field', 'default': False, 'attr': 'is_swap_prime_field'}> = <_PropertyDeferred, <built-in function BoolProperty>, {'name': 'Swap Prime Field', 'default': False, 'attr': 'is_swap_prime_field'}>
was_t_stance = False
@classmethod
def poll(cls, context):
175    @classmethod
176    def poll(cls, context):
177        ob = context.active_object
178        if ob and ob.type == 'ARMATURE':
179            return True
180        return False
def invoke(self, context, event):
182    def invoke(self, context, event):
183        self.was_t_stance = context.object.data.get('is T Stance')
184        return context.window_manager.invoke_props_dialog(self)
def draw(self, context):
186    def draw(self, context):
187        self.layout.prop(self, 'is_apply_armature_modifier')
188
189        col = self.layout.column()
190        col.enabled = self.is_apply_armature_modifier
191        col.prop(self , 'is_preserve_shape_key_values')
192        col.prop(self , 'is_deform_preserve_volume'   )
193        if compat.IS_LEGACY:
194            col.prop(prefs, 'custom_normal_blend', icon=compat.icon('SNAP_NORMAL'  ), slider=True)
195
196        self.layout.prop(self, 'is_bake_drivers')
197        if self.was_t_stance:
198            self.layout.prop(self, 'is_keep_original')
def execute(self, context):
200    def execute(self, context):
201        ob = context.active_object
202        arm = ob.data
203        pose = ob.pose
204        progress = 0
205
206        pre_selected_objects = context.selected_objects
207        pre_selected_pose_bones = context.selected_pose_bones
208        pre_mode = ob.mode
209        pre_frame = context.scene.frame_current
210
211        bpy.ops.object.mode_set(mode='OBJECT')
212        bpy.ops.object.select_all(action='DESELECT')
213        compat.set_select(ob, True)
214
215        if self.is_swap_prime_field:
216            #context.scene.frame_set(1)
217            bpy.ops.poselib.apply_pose(pose_index=1)
218            bpy.context.view_layer.update()
219
220        if self.is_apply_armature_modifier and ob.children:
221            override = context.copy()
222            context.window_manager.progress_begin(0, len(ob.children)+1)  
223            for child in ob.children:
224                override['object'], override['active_object'] = child, child
225                if child.type == 'MESH' and len(child.modifiers) and bpy.ops.object.forced_modifier_apply.poll(override):
226                    for mod in child.modifiers:
227                        if mod.type == 'ARMATURE':
228                            mod.use_deform_preserve_volume = self.is_deform_preserve_volume
229                            if not mod.object == ob:
230                                had_armature = False
231                            else:
232                                had_armature = True
233                                old_name                = mod.name                      
234                                old_show_expanded       = mod.show_expanded             
235                                old_show_in_editmode    = mod.show_in_editmode          
236                                old_show_on_cage        = mod.show_on_cage              
237                                old_show_render         = mod.show_render               
238                                old_show_viewport       = mod.show_viewport             
239                                old_use_apply_on_spline = mod.use_apply_on_spline       
240                                old_invert_vertex_group = mod.invert_vertex_group       
241                                old_use_bone_envelopes  = mod.use_bone_envelopes        
242                                #old_use_multi_modifier  = mod.use_multi_modifier        
243                                old_use_vertex_groups   = mod.use_vertex_groups         
244                                old_vertex_group        = mod.vertex_group        
245                    apply_results = bpy.ops.object.forced_modifier_apply(override, apply_viewport_visible=True, is_preserve_shape_key_values=self.is_preserve_shape_key_values, initial_progress=progress)
246                    if ('FINISHED' in apply_results) and had_armature:
247                        new_mod = child.modifiers.new(name=old_name, type='ARMATURE')
248                        new_mod.object              = ob
249                        new_mod.use_deform_preserve_volume = self.is_deform_preserve_volume
250                        new_mod.show_expanded       = old_show_expanded      
251                        new_mod.show_in_editmode    = old_show_in_editmode   
252                        new_mod.show_on_cage        = old_show_on_cage       
253                        new_mod.show_render         = old_show_render        
254                        new_mod.show_viewport       = old_show_viewport      
255                        new_mod.use_apply_on_spline = old_use_apply_on_spline
256                        new_mod.invert_vertex_group = old_invert_vertex_group
257                        new_mod.use_bone_envelopes  = old_use_bone_envelopes 
258                        #new_mod.use_multi_modifier  = old_use_multi_modifier 
259                        new_mod.use_vertex_groups   = old_use_vertex_groups  
260                        new_mod.vertex_group        = old_vertex_group
261                
262                progress += 1
263                context.window_manager.progress_update(progress)
264
265        else:
266            context.window_manager.progress_begin(0, 1)  
267
268        temp_ob = ob.copy()
269        temp_arm = arm.copy()
270        temp_ob.data = temp_arm
271        compat.link(context.scene, temp_ob)
272        
273        compat.set_active(context, ob)
274        bpy.ops.object.mode_set(mode='POSE')
275        bpy.ops.pose.select_all(action='SELECT')
276        for bone in ob.pose.bones:
277            prime_scale = mathutils.Vector(bone.get('prime_scale', (1.0,1.0,1.0)))
278            bone_scale = bone.scale #bone.matrix.to_scale()
279            prime_scale.x *= bone_scale.x
280            prime_scale.y *= bone_scale.y
281            prime_scale.z *= bone_scale.z
282            bone['prime_scale'] = prime_scale
283            #bone['_RNA_UI']['prime_scale']['subtype'] = 'XYZ'
284        bpy.ops.pose.armature_apply()
285        bpy.ops.pose.constraints_clear()
286        ob.animation_data_clear()
287        
288        if arm.get("is T Stance") and self.is_keep_original and not self.is_swap_prime_field:
289            anim_data = temp_ob.animation_data
290            if anim_data and anim_data.drivers:
291                drivers = anim_data.drivers
292                for driver in drivers.values():
293                    drivers.remove(driver)
294            #context.scene.frame_set(1)
295            bpy.ops.pose.user_transforms_clear()
296            bpy.ops.poselib.apply_pose(pose_index=1)
297        else:
298            compat.set_active(context, temp_ob)
299            bpy.ops.object.mode_set(mode='POSE')
300            bpy.ops.pose.select_all(action='SELECT')
301            temp_ob.animation_data_clear()
302            bpy.ops.pose.transforms_clear()
303            bpy.ops.object.mode_set(mode='OBJECT')
304            compat.set_select(temp_ob, False)
305        
306        if self.is_swap_prime_field and arm.get('is T Stance'):
307            arm['is T Stance'] = False
308        else:
309            arm['is T Stance'] = True
310
311        # CNV_OT_copy_prime_field.execute()
312        compat.set_select(temp_ob, True)
313        compat.set_active(context, ob)
314        bpy.context.view_layer.update()
315        response = bpy.ops.pose.copy_prime_field(is_only_selected=False, is_key_location=True, is_key_scale=True, is_apply_prime=(not self.is_swap_prime_field))#is_key_location=self.is_bake_drivers, is_key_scale=self.is_bake_drivers, is_apply_prime=True)
316
317        context.window_manager.progress_end()
318
319        if not 'FINISHED' in response:
320            return response
321
322        common.remove_data(temp_arm)
323        try:
324            common.remove_data(temp_ob)
325        except:
326            pass
327        
328        bpy.ops.object.mode_set(mode='POSE')
329        bpy.ops.pose.select_all(action='DESELECT')
330        if pre_selected_pose_bones:
331            for bone in pre_selected_pose_bones:
332                arm.bones[bone.name].select = True
333
334        if pre_selected_objects:
335            for o in pre_selected_objects:
336                compat.set_select(o, True)
337        compat.set_active(context, ob)
338        bpy.ops.object.mode_set(mode=pre_mode)
339
340        context.scene.frame_set(pre_frame)
341
342
343
344        return {'FINISHED'}
bl_rna = <bpy_struct, Struct("POSE_OT_apply_prime_field")>
Inherited Members
bpy_types.Operator
as_keywords
poll_message_set
builtins.bpy_struct
keys
values
items
get
pop
as_pointer
keyframe_insert
keyframe_delete
driver_add
driver_remove
is_property_set
property_unset
is_property_hidden
is_property_readonly
is_property_overridable_library
property_overridable_library_set
path_resolve
path_from_id
type_recast
bl_rna_get_subclass_py
bl_rna_get_subclass
id_properties_ensure
id_properties_clear
id_properties_ui
id_data